package com.heimali.happyreader.ui;

import java.util.ArrayList;

import com.heimali.happyreader.R;
import com.heimali.happyreader.utils.SystemUtils;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnFocusChangeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class QAccountEditText extends LinearLayout {

	private final static String TAG = "QAccountEditText";
	private final String SEPERATOR = "@";
	private final String[] defaultMailList = { "163.com", "126.com", "hotmail.com", "gmail.com", "sina.com",
			"sohu.com", "qq.com", "yahoo.com.cn", "yahoo.cn", "yeah.net", "live.cn", "tom.com" };
	private String lastLoggedAccount = ""; // 上次登录的账号
	private String lastInputStr = ""; // 最后输入的字符串
	private Context context;
	private AutoCompleteTextView autoComplete;
	private Boolean showLastLoggedAccount = false; // 是否显示上次登录的账号
	private Boolean autoCompleteSetWidthFlag = false; // 设置宽度的标识
	private SelectedCallback dropDownItemSelectedCallback;

	private ImageButton delBtn;
	private ArrayAdapter<String> adapter = null;
	private ArrayList<String> dropdownList = new ArrayList<String>();
	private ArrayList<EmailCount> mailList = new ArrayList<EmailCount>();

	// spf : sharedPreferences field
	private String spfMailList = "LoginMailList";
	private String spfAccount = "Account";
	private SharedPreferences sharedPreferences = null;

	private float density = -1;

	public interface SelectedCallback {
		public void run();
	}

	public QAccountEditText(Context context) {
		this(context, null);
	}

	public QAccountEditText(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public QAccountEditText(final Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs);
		this.context = context;
		getScreenInfo();
		mailList = readMailList();
		sort(mailList);

		RelativeLayout view = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.qaet_view, null);
		delBtn = (ImageButton) view.findViewById(R.id.qaet_delete);
		delBtn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (showLastLoggedAccount) {
					String inputStr = autoComplete.getText().toString();
					if (lastLoggedAccount.equals(inputStr)) {
						clearLastLoggedAccount();
					}
				}
				autoComplete.setText("");
				delBtn.setVisibility(View.INVISIBLE);
			}
		});

		int resourceID = -1;
		autoComplete = (AutoCompleteTextView) view.findViewById(R.id.qaet_autoComplete);
		TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.QAccountEditText);
		resourceID = arr.getResourceId(R.styleable.QAccountEditText_showLastAccount, 0);
		showLastLoggedAccount = resourceID > 0 ? arr.getResources().getBoolean(resourceID) : arr.getBoolean(
				R.styleable.QAccountEditText_showLastAccount, false);
		if (showLastLoggedAccount) {
			lastLoggedAccount = readLoggedAccount();
			autoComplete.setText(lastLoggedAccount);
		}

		resourceID = arr.getResourceId(R.styleable.QAccountEditText_hint, 0);
		autoComplete.setHint(resourceID > 0 ? arr.getResources().getText(resourceID) : arr
				.getString(R.styleable.QAccountEditText_hint)); // hint不给默认值

		resourceID = arr.getResourceId(R.styleable.QAccountEditText_textSize, 0);
		CharSequence textSize = resourceID > 0 ? arr.getResources().getText(resourceID) : arr
				.getString(R.styleable.QAccountEditText_textSize);
		float defaultTextSize = 16.0f;
		autoComplete.setTextSize(textSize != null ? Float.valueOf(textSize.toString()) : defaultTextSize);

		autoComplete.setDropDownBackgroundResource(R.drawable.qaet_piece);
		autoComplete.addTextChangedListener(new TextWatcher() {
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				String inputStr = autoComplete.getText().toString();
				if (inputStr.equals(lastInputStr)) {
					return;
				}
				lastInputStr = inputStr;
				updateDropdownList(inputStr);
				adapter = new ArrayAdapter<String>(context, R.layout.qaet_item, dropdownList);
				autoComplete.setAdapter(adapter);
				if (!autoCompleteSetWidthFlag) {
					autoComplete.setDropDownWidth(autoComplete.getWidth() + 4);
					autoCompleteSetWidthFlag = true;
				}
				delBtn.setVisibility(inputStr.length() > 0 ? View.VISIBLE : View.INVISIBLE);
			}

			public void beforeTextChanged(CharSequence s, int start, int count, int after) {
			}

			public void afterTextChanged(Editable s) {
			}
		});
		autoComplete.setOnFocusChangeListener(new OnFocusChangeListener() {
			public void onFocusChange(View v, boolean hasFocus) {
				if (hasFocus) {
					String inputStr = autoComplete.getText().toString();
					delBtn.setVisibility(inputStr.length() > 0 ? View.VISIBLE : View.INVISIBLE);
				} else {
					delBtn.setVisibility(View.INVISIBLE);
				}
			}
		});
		autoComplete.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				if (dropDownItemSelectedCallback != null) {
					dropDownItemSelectedCallback.run();
				}
			}
		});
		addView(view);
		arr.recycle();
	}

	private void updateDropdownList(String inputStr) {
		dropdownList.clear();
		int seperatorPosition = inputStr.indexOf(SEPERATOR);
		String mailName = "", mailSuffix = "";
		if (seperatorPosition > 0) {
			mailName = inputStr.substring(0, seperatorPosition);
			mailSuffix = inputStr.substring(seperatorPosition + 1, inputStr.length());
		}
		if (mailName != null && mailName.length() > 0) {
			mailName += SEPERATOR;
			for (int i = 0, len = mailList.size(); i < len; i++) {
				EmailCount obj = (EmailCount) mailList.get(i);
				if (obj.email.startsWith(mailSuffix)) {
					String item = mailName + obj.email;
					dropdownList.add(item);
				}
			}
		}
	}

	private void getScreenInfo() {
		DisplayMetrics dm = new DisplayMetrics();
		((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm);
		density = dm.density;
	}

	public Editable getText() {
		return autoComplete.getText();
	}

	public void setText(String value) {
		lastInputStr = value;
		autoComplete.setText(value);
	}

	public boolean setFocus() {
		return autoComplete.requestFocus();
	}

	public void setSelectedCallback(SelectedCallback callback) {
		dropDownItemSelectedCallback = callback;
	}

	public void setDropDownWidth(int width) {
		autoComplete.setDropDownWidth(width);
		autoComplete.setDropDownHorizontalOffset(autoComplete.getWidth() - width + (int) (density * 4));
		autoCompleteSetWidthFlag = true;
	}

	public void statAccount() {
		String account = autoComplete.getText().toString();
		saveLoggedAccount(account);

		int seperatorPosition = account.indexOf(SEPERATOR);
		if (seperatorPosition == -1) {
			return;
		}

		String mailSuffix = account.substring(seperatorPosition + 1, account.length());
		boolean flag = false;
		for (int i = 0, len = mailList.size(); i < len; i++) {
			EmailCount obj = (EmailCount) mailList.get(i);
			if (mailSuffix.equals(obj.email)) {
				obj.count++;
				flag = true;
				break;
			}
		}

		if (!flag) {
			int defautCount = 1;
			mailList.add(new EmailCount(mailSuffix, defautCount));
		}
		saveMailList();
	}

	public void clearLastLoggedAccount() {
		saveLoggedAccount("");
	}

	private void checkAccountInfoSP() {
		if (sharedPreferences == null) {
			sharedPreferences = context.getSharedPreferences("account_info", Context.MODE_PRIVATE);
		}
	}

	private void saveLoggedAccount(String account) {
		checkAccountInfoSP();
		Editor edit = sharedPreferences.edit();
		edit.putString(spfAccount, account);
		edit.commit();
	}

	private String readLoggedAccount() {
		checkAccountInfoSP();
		return sharedPreferences.getString(spfAccount, "");
	}

	private String serialize(ArrayList<EmailCount> list) {
		String str = "";
		if (list.isEmpty()) {
			return str;
		}

		for (EmailCount item : list) {
			str += item.email + "|" + item.count + "||";
		}

		return str.substring(0, str.length() - 2);
	}

	private ArrayList<EmailCount> unSerialize(String str) {
		// 126.com|1||163.com|0||qq.com|0||sina.com.cn|0||sohu.com|0||gmail.com|0||hotmail.com|0||live.cn|0||yeah.net|0||yahoo.com.cn|0
		if (str == null || "".equals(str)) {
			return getDefaultMailList();
		}

		ArrayList<EmailCount> list = new ArrayList<EmailCount>();
		String[] items = str.split("\\|\\|");
		for (int i = 0, len = items.length; i < len; i++) {
			String[] item = items[i].split("\\|");
			list.add(new EmailCount(item[0], Integer.valueOf(item[1])));
		}
		return list;
	}

	private void saveMailList() {
		checkAccountInfoSP();
		Editor edit = sharedPreferences.edit();
		edit.putString(spfMailList, serialize(mailList));
		edit.commit();
	}

	private ArrayList<EmailCount> readMailList() {
		checkAccountInfoSP();
		String configMailListStr = sharedPreferences.getString(spfMailList, "");
		return unSerialize(configMailListStr);
	}

	private ArrayList<EmailCount> getDefaultMailList() {
		ArrayList<EmailCount> list = new ArrayList<EmailCount>();
		for (int i = 0, len = defaultMailList.length; i < len; i++) {
			list.add(new EmailCount(defaultMailList[i], 0));
		}
		return list;
	}

	private ArrayList<EmailCount> sort(ArrayList<EmailCount> sortList) {
		// Collections.sort(sortList, new Comparator<EmailCount>() {
		// public int compare(EmailCount obj1, EmailCount obj2) {
		// return obj2.count - obj1.count;
		// }
		// });
		// return sortList;

		// --------------------------------------------------------------
		// 以上代码不能满足需求， 如两个邮箱使用次数一样， 最近使用的邮箱靠前显示

		ArrayList<EmailCount> tmpList = new ArrayList<EmailCount>();
		for (int i = 0, len = sortList.size(); i < len; i++) {
			EmailCount item = (EmailCount) sortList.get(i);
			if (item.count <= 0) {
				continue;
			}

			int tmpLen = tmpList.size(), idx = tmpLen;
			for (int j = 0; j < tmpLen; j++) {
				EmailCount tmpItem = (EmailCount) tmpList.get(j);
				if (tmpItem.count <= item.count) {
					idx = j;
					break;
				}
			}
			tmpList.add(idx, item);

			sortList.remove(i);
			i--;
			len--;
		}
		sortList.addAll(0, tmpList);
		return sortList;
	}

	public class EmailCount {
		public String email;
		public int count;

		public EmailCount(String email, int count) {
			this.email = email;
			this.count = count;
		}
	}

}
